/**
 * Carnegie Mellon University
 * School of Computer Science
 * MSIT eBusiness Technology
 * 
 * Team 8 - Infinity (2011 Spring)
 * infinity-team8@googlegroups.com
 * 
 * Professor: Jeffrey L. Eppinger
 * Program Faculty: Sujata Telang
 */

package model;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;

import org.mybeans.dao.DAOException;
import org.mybeans.factory.BeanFactory;
import org.mybeans.factory.BeanFactoryException;
import org.mybeans.factory.BeanTable;
import org.mybeans.factory.DuplicateKeyException;
import org.mybeans.factory.MatchArg;
import org.mybeans.factory.RollbackException;
import org.mybeans.factory.Transaction;

import databean.PositionBean;
import databean.TransactionBean;


public class PositionDAO {
	private BeanFactory<PositionBean> factory;
	
	public PositionDAO() throws DAOException {
		try {
			// Get a BeanTable so we can create the "user" table
	        BeanTable<PositionBean> positionTable = BeanTable.getInstance(PositionBean.class,"position");
	        
	        if (!positionTable.exists()) positionTable.create("customerID", "fundID");
	        
	        // Long running web apps need to clean up idle database connections.
	        // So we can tell each BeanTable to clean them up.  (You would only notice
	        // a problem after leaving your web app running for several hours.)
	        positionTable.setIdleConnectionCleanup(true);
	
	        // Get a BeanFactory which the actions will use to read and write rows of the "user" table
	        factory = positionTable.getFactory();
	        
	        
		} catch (BeanFactoryException e) {
			throw new DAOException(e);
		}
	}
	
	public void create(PositionBean position) throws DAOException {
		try {
	    	
        	Transaction.begin();
        	
        	PositionBean dbPosition = factory.create(position.getCustomerID(), position.getFundID());
        	dbPosition.setShares(position.getShares());
        	
			Transaction.commit();
			
		} catch (DuplicateKeyException e) {
			throw new DAOException(e);
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive()) Transaction.rollback();
		}
	}
	
	
	public void remove(PositionBean position) throws DAOException {
		try {
	    	
        	Transaction.begin();
        	
        	factory.delete(position.getCustomerID(), position.getFundID());
        	
			Transaction.commit();
			
		} catch (DuplicateKeyException e) {
			throw new DAOException(e);
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive()) Transaction.rollback();
		}
	}
	
	
	/**
	 * lookup position by customer id
	 * @param name
	 * @return
	 * @throws DAOException
	 */
	public PositionBean[] lookup(long customerID) throws DAOException {
		try {
			
			if (factory.match(MatchArg.equals("customerID", customerID)) == null ||
            		factory.match(MatchArg.equals("customerID", customerID)).length == 0) {
				return null;
			} else {
				return factory.match(MatchArg.equals("customerID", customerID));
			}
			
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	
	/**
	 * lookup position by customer id and fund id
	 * @param name
	 * @return
	 * @throws DAOException
	 */
	public PositionBean lookup(long customerID, long fundID) throws DAOException {
		try {
			return factory.lookup(customerID, fundID);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}		
	}
	
	/**
	 * look up available shares by customer id and fund id
	 * @param userName
	 * @return
	 * @throws DAOException
	 */
	public long getAvailableShares(long customerID, long fundID) throws DAOException {
		
		PositionBean position = lookup(customerID, fundID);
		long availableShares = position.getShares();
		
		TransactionDAO transactionDAO = new TransactionDAO();
		TransactionBean[] transactions = transactionDAO.getPendingTransactions();
		
		for (int i = 0; i<transactions.length; i++) {
			if (transactions[i].getCustomerID() == position.getCustomerID()) {

				if (transactions[i].getTransactionType().equals("sell")) {
					if (transactions[i].getFundID() == position.getFundID()) {
						availableShares = availableShares - transactions[i].getShares();
					}
				}
				
			}
		}
		
		return availableShares;
	}
	
	
	/**
	 * get formatted available shares
	 */
	public String getAvailableSharesFormatted(long customerID, long fundID) throws DAOException {
		long shares = getAvailableShares(customerID, fundID);
		
		NumberFormat formatter = new DecimalFormat("##0.000");
		String s = formatter.format( ((double)shares/1000) );
		
		return s;
	}
	
	/**
	 * get formatted shares
	 */
	public String getSharesFormatted(long customerID, long fundID) throws DAOException {
		PositionBean position = lookup(customerID, fundID);
		long shares = position.getShares();
		
		NumberFormat formatter = new DecimalFormat("##0.000");
		String s = formatter.format( ((double)shares/1000) );
		
		return s;
	}
	
	
	public void modify(PositionBean position) throws DAOException {
		try {
    	
        	Transaction.begin();
        	
        	PositionBean dbPosition = factory.lookup(position.getCustomerID(), position.getFundID());
        	dbPosition.setShares(position.getShares());
        	
			Transaction.commit();
			
		} catch (DuplicateKeyException e) {
			throw new DAOException(e);
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive()) Transaction.rollback();
		}
	}
	
	
	protected BeanFactory<PositionBean> getFactory() { return factory; }
	
	public PositionBean[] getPositions() throws DAOException {
		try {
			PositionBean[] positions = factory.match();
			Arrays.sort(positions);
			return positions;
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
}
